廢話不多說,今日流程如下先觀察傳進內容,在針對內容刻畫面
指定 /payment
// routes/web.php
Route::post('/payment', [Web::class, 'payment']);
在 Controller 建立 payment 函數,先 dd 傳送的要求看內容
public function payment(Request $request)
{
dd($request->all());
return view('payment', [
'dataset' => $request->all()
]);
}
建立信用卡訂單並模擬付款完成的時候,覺得一切順利的時候,跳出這個畫面
查到這篇 stack overflow 的文章 後發現是 csrf protection
的問題,需要去把這個路徑加進排外名單
// app/Http/Middleware/VerifyCsrfToken.php
protected $except = [
'/payment'
];
補充一個看傳入的方法,不用寫 dd 印出
開啟開發者工具(F12) -> Network -> All -> 選擇 payment -> Header 拉到最下面有 Form Data 的內容
看來跟 receive_msg 一樣,只是需要能回吐解密訊息,那就修改一下這個函數,增加一個參數 return_data,其為 true 時則回傳 data
// app/Http/Controllers/Controller.php
public function receive_msg(Request $request, bool $return_data = false)
{
Log::alert('Receive message Content', $request->all());
$PayToken = $request->get('PayToken');
if (!$PayToken) {
Log::alert('PayToken Not exist');
return ['Status' => 'F'];
}
$sinopac = $this->initSinopac();
$data = $sinopac->requestDataset('OrderPayQuery', $request->all());
$message = $sinopac->callApi('https://apisbx.sinopac.com/funBIZ/QPay.WebAPI/api/Order', $data);
$decrypt_message = $this->reply_message_decrypt($sinopac, $message);
Log::info('Reply message', (array) $decrypt_message);
$record = sale_order::where('ts_no', $decrypt_message['TSResultContent']['TSNo']);
if (!$record->count()) {
Log::alert('Not found order!');
return ['Status' => 'F'];
}
$record->update([
'pay_token' => $decrypt_message['PayToken'],
'ap_type' => $decrypt_message['TSResultContent']['APType'],
'status' => $decrypt_message['Status'],
'description' => $decrypt_message['Description']
]);
return $return_data ? $decrypt_message : ['Status' => 'S'];
}
接著修改 Web Controller 的 payment,因為是繼承 Controller,所以可以呼叫到 receive_msg
// app/Http/Controllers/Web.php
public function payment(Request $request)
{
$message = $this->receive_msg($request, true);
$order = sale_order::where('ts_no', $message['TSResultContent']['TSNo']);
$paid = false;
$display_message = '付款尚未完成';
if ($message['TSResultContent']['APType'] === 'PayOut') {
$order->update([
'pay_datetime' => DateTime::createFromFormat('YmdHi', $message['TSResultContent']['PayDate'])
]);
$paid = true;
$display_message = '付款完成';
}
return view('payment', [
'paid' => $paid,
'message' => $display_message,
'order_no' => $order->first()->order_no
]);
}
接著增加 payment.blade.php
// resources/views/payment.blade.php
<h2>訂單 {{ $order_no }}</h2>
<h1>{{ $message }}</h1>
爬 Log 把剛剛紀錄的 json 複製到 Postmen 傳一次要求,看個結果
重新產生信用卡訂單後再模擬付款一次,跳轉回來的畫面就跟預想的一樣
再看一下訂單清單,有寫進去就行了
一開始想說需要再寫一次 initSinopac,突然看到 Web 是繼承 Controller
節省不少重寫的時間
明天把查詢訂單API解讀一下,寫個Controller,畫面的話就看時間吧。